import { create } from 'zustand';
import { devtools, persist } from 'zustand/middleware';
import type { AppState, AppEvent, ExperienceModeConfig } from '@/types';

const EXPERIENCE_MODES: Record<string, ExperienceModeConfig> = {
  education: {
    id: 'education',
    name: '🎓 教育模式',
    speed: 0.8,
    showTechDetails: true,
    pauseAtKeyPoints: true,
    includeQuizzes: true
  },
  quick: {
    id: 'quick',
    name: '⚡ 快速演示',
    speed: 1.5,
    showTechDetails: false,
    skipTransitions: false,
    highlightMainPoints: true
  },
  developer: {
    id: 'developer',
    name: '🧑 开发者模式',
    speed: 1.0,
    showCode: true,
    showLogs: true,
    allowManualInput: true,
    debugMode: true,
    showTechDetails: true
  },
  presentation: {
    id: 'presentation',
    name: '🎪 演讲模式',
    speed: 1.0,
    fullscreen: true,
    noControls: true,
    autoplay: true,
    dramaticEffects: true,
    showTechDetails: false
  }
};

const initialState: AppState = {
  animation: {
    currentStage: 0,
    isPlaying: false,
    playbackSpeed: 1.0,
    currentTime: 0,
    totalDuration: 70000,
    isTransitioning: false
  },
  experienceMode: EXPERIENCE_MODES.education,
  audioSettings: {
    enabled: true,
    volume: 0.7,
    soundEffects: true,
    backgroundMusic: false
  },
  visualSettings: {
    theme: 'dark',
    reducedMotion: false,
    highContrast: false,
    particleCount: 500,
    animationQuality: 'high'
  },
  zkProofData: null,
  blockchainTx: null,
  userProgress: {
    completedStages: [],
    bookmarks: [],
    totalWatchTime: 0,
    quizScores: {},
    achievements: [],
    lastVisited: Date.now()
  },
  performance: {
    frameRate: 60,
    memoryUsage: 0,
    loadTime: 0,
    animationLag: 0,
    apiLatency: 0
  },
  sidebarOpen: false,
  fullscreen: false,
  loading: true,
  error: null
};

interface AppStore extends AppState {
  // Actions
  dispatch: (event: AppEvent) => void;
  
  // Animation controls
  play: () => void;
  pause: () => void;
  reset: () => void;
  jumpToStage: (stage: number) => void;
  setSpeed: (speed: number) => void;
  updateTime: (time: number) => void;
  
  // Mode management
  setExperienceMode: (modeId: string) => void;
  
  // Settings
  updateAudioSettings: (settings: Partial<AppState['audioSettings']>) => void;
  updateVisualSettings: (settings: Partial<AppState['visualSettings']>) => void;
  
  // Data management
  setZKProofData: (data: AppState['zkProofData']) => void;
  setBlockchainTx: (tx: AppState['blockchainTx']) => void;
  generateNewProofData: (preImage: string) => Promise<boolean>;
  callBlockchain: (useSimulation?: boolean) => Promise<boolean>;
  callRecordAssetOnly: (useSimulation?: boolean) => Promise<boolean>;
  callVerifyAssetZKOnly: (useSimulation?: boolean) => Promise<boolean>;
  
  // Progress tracking
  completeStage: (stageId: string) => void;
  addBookmark: (time: number) => void;
  updateWatchTime: (duration: number) => void;
  
  // UI state
  toggleSidebar: () => void;
  toggleFullscreen: () => void;
  setLoading: (loading: boolean) => void;
  setError: (error: string | null) => void;
  
  // Performance monitoring
  updatePerformance: (metrics: Partial<AppState['performance']>) => void;
}

export const useAppStore = create<AppStore>()(
  devtools(
    persist(
      (set, get) => ({
        ...initialState,

        dispatch: (event: AppEvent) => {
          const state = get();
          switch (event.type) {
            case 'PLAY':
              set({ animation: { ...state.animation, isPlaying: true } });
              break;
            case 'PAUSE':
              set({ animation: { ...state.animation, isPlaying: false } });
              break;
            case 'RESET':
              set({ 
                animation: { 
                  ...state.animation, 
                  currentStage: 0, 
                  currentTime: 0, 
                  isPlaying: false 
                } 
              });
              break;
            case 'JUMP_TO_STAGE':
              set({ 
                animation: { 
                  ...state.animation, 
                  currentStage: event.payload,
                  isTransitioning: true
                } 
              });
              break;
            case 'SET_SPEED':
              set({ 
                animation: { 
                  ...state.animation, 
                  playbackSpeed: event.payload 
                } 
              });
              break;
            case 'SET_MODE':
              set({ experienceMode: event.payload });
              break;
            case 'STAGE_COMPLETE':
              const completedStages = [...state.userProgress.completedStages];
              if (!completedStages.includes(event.payload)) {
                completedStages.push(event.payload);
              }
              set({
                userProgress: {
                  ...state.userProgress,
                  completedStages
                }
              });
              break;
            case 'ADD_BOOKMARK':
              set({
                userProgress: {
                  ...state.userProgress,
                  bookmarks: [...state.userProgress.bookmarks, event.payload]
                }
              });
              break;
            case 'UPDATE_PROGRESS':
              set({
                userProgress: {
                  ...state.userProgress,
                  ...event.payload
                }
              });
              break;
            case 'SET_ERROR':
              set({ error: event.payload });
              break;
            case 'CLEAR_ERROR':
              set({ error: null });
              break;
          }
        },

        // Animation controls
        play: () => set(state => ({ 
          animation: { ...state.animation, isPlaying: true } 
        })),
        
        pause: () => set(state => ({ 
          animation: { ...state.animation, isPlaying: false } 
        })),
        
        reset: () => set(state => ({ 
          animation: { 
            ...state.animation, 
            currentStage: 0, 
            currentTime: 0, 
            isPlaying: false 
          } 
        })),
        
        jumpToStage: (stage: number) => set(state => ({ 
          animation: { 
            ...state.animation, 
            currentStage: stage,
            isTransitioning: true
          } 
        })),
        
        setSpeed: (speed: number) => set(state => ({ 
          animation: { ...state.animation, playbackSpeed: speed } 
        })),
        
        updateTime: (time: number) => set(state => ({ 
          animation: { 
            ...state.animation, 
            currentTime: time,
            isTransitioning: false
          } 
        })),

        // Mode management
        setExperienceMode: (modeId: string) => {
          const mode = EXPERIENCE_MODES[modeId];
          if (mode) {
            set({ experienceMode: mode });
            // Apply mode-specific settings
            if (mode.speed) {
              set(state => ({ 
                animation: { ...state.animation, playbackSpeed: mode.speed } 
              }));
            }
          }
        },

        // Settings
        updateAudioSettings: (settings) => set(state => ({
          audioSettings: { ...state.audioSettings, ...settings }
        })),
        
        updateVisualSettings: (settings) => set(state => ({
          visualSettings: { ...state.visualSettings, ...settings }
        })),

        // Data management
        setZKProofData: (data) => set({ zkProofData: data }),
        setBlockchainTx: (tx) => set({ blockchainTx: tx }),
        
        generateNewProofData: async (preImage: string) => {
          try {
            set({ loading: true, error: null });
            
            // 确保preImage是字符串类型
            const preImageStr = String(preImage).trim();
            
            if (!preImageStr) {
              throw new Error('PreImage cannot be empty');
            }
            
            console.log('🔄 Generating proof data for preImage:', preImageStr);
            
            // 动态导入数据生成服务
            const { generateZKProofData } = await import('@/services/dataGenerator');
            
            // 生成新的证明数据
            const newData = await generateZKProofData(preImageStr);
            
            // 更新状态
            set({ 
              zkProofData: newData,
              loading: false 
            });
            
            console.log('✅ Successfully generated new proof data for preImage:', preImageStr);
            return true;
            
          } catch (error) {
            console.error('❌ Failed to generate proof data:', error);
            set({ 
              loading: false, 
              error: '数据生成失败：' + (error instanceof Error ? error.message : '未知错误')
            });
            return false;
          }
        },
        
        callBlockchain: async (useSimulation = false) => {
          try {
            const state = get();
            
            if (!state.zkProofData) {
              throw new Error('No proof data available for blockchain call');
            }
            
            set({ loading: true, error: null });
            
            // 动态导入区块链服务
            const { callBlockchain, simulateBlockchainCall } = await import('@/services/blockchainService');
            
            // 根据参数选择真实调用还是模拟调用
            const result = useSimulation 
              ? await simulateBlockchainCall(state.zkProofData)
              : await callBlockchain(state.zkProofData);
            
            if (result.success && result.transaction) {
              // 更新区块链交易状态
              set({ 
                blockchainTx: result.transaction,
                loading: false 
              });
              
              console.log('✅ Blockchain call completed successfully');
              return true;
            } else {
              // 处理失败情况
              set({ 
                loading: false,
                error: result.error || 'Blockchain call failed'
              });
              
              console.error('❌ Blockchain call failed:', result.error);
              return false;
            }
            
          } catch (error) {
            console.error('❌ Blockchain call error:', error);
            set({ 
              loading: false, 
              error: '区块链调用失败：' + (error instanceof Error ? error.message : '未知错误')
            });
            return false;
          }
        },

        // Stage4专用：仅调用recordAsset进行数据上链
        callRecordAssetOnly: async (useSimulation = false) => {
          try {
            const state = get();
            
            if (!state.zkProofData) {
              throw new Error('No proof data available for recordAsset call');
            }
            
            set({ loading: true, error: null });
            console.log('🏗️ Stage4: 开始数据上链操作 (recordAsset)');
            
            // 动态导入区块链服务
            const { recordAssetToBlockchain, simulateRecordAsset } = await import('@/services/blockchainService');
            
            // 根据参数选择真实调用还是模拟调用
            const result = useSimulation 
              ? await simulateRecordAsset(state.zkProofData)
              : await recordAssetToBlockchain(state.zkProofData);
            
            if (result.success && result.transaction) {
              // 只存储数据上链的交易记录
              set({ 
                blockchainTx: {
                  ...result.transaction,
                  type: 'recordAsset', // 标记为数据上链交易
                  stage: 'stage4'
                },
                loading: false 
              });
              
              console.log('✅ Stage4: 数据上链完成');
              console.log('📝 交易类型: recordAsset');
              console.log('🔗 交易哈希:', result.transaction.txHash);
              return true;
            } else {
              // 处理失败情况
              set({ 
                loading: false,
                error: result.error || 'RecordAsset call failed'
              });
              
              console.error('❌ Stage4: 数据上链失败:', result.error);
              return false;
            }
            
          } catch (error) {
            console.error('❌ Stage4: 数据上链调用错误:', error);
            set({ 
              loading: false, 
              error: '数据上链失败：' + (error instanceof Error ? error.message : '未知错误')
            });
            return false;
          }
        },

        // Stage5专用：仅调用verifyAssetZKPacked进行零知识证明验证
        callVerifyAssetZKOnly: async (useSimulation = false) => {
          try {
            const state = get();
            
            if (!state.zkProofData) {
              throw new Error('No proof data available for verifyAssetZKPacked call');
            }
            
            set({ loading: true, error: null });
            console.log('🔍 Stage5: 开始零知识证明验证 (verifyAssetZKPacked)');
            
            // 动态导入区块链服务
            const { verifyAssetZKProof, simulateVerifyAssetZK } = await import('@/services/blockchainService');
            
            // 根据参数选择真实调用还是模拟调用
            const result = useSimulation 
              ? await simulateVerifyAssetZK(state.zkProofData)
              : await verifyAssetZKProof(state.zkProofData);
            
            if (result.success && result.transaction) {
              // 存储验证交易记录，保留之前的数据上链记录
              const previousTx = state.blockchainTx;
              set({ 
                blockchainTx: {
                  ...result.transaction,
                  type: 'verifyAssetZKPacked', // 标记为验证交易
                  stage: 'stage5',
                  previousTransaction: previousTx || undefined // 保留前一个交易记录
                },
                loading: false 
              });
              
              console.log('✅ Stage5: 零知识证明验证完成');
              console.log('📝 交易类型: verifyAssetZKPacked');
              console.log('🔗 验证交易哈希:', result.transaction.txHash);
              console.log('✅ 验证结果:', result.transaction.verificationResult);
              return true;
            } else {
              // 处理失败情况
              set({ 
                loading: false,
                error: result.error || 'VerifyAssetZKPacked call failed'
              });
              
              console.error('❌ Stage5: 零知识证明验证失败:', result.error);
              return false;
            }
            
          } catch (error) {
            console.error('❌ Stage5: 零知识证明验证调用错误:', error);
            set({ 
              loading: false, 
              error: '零知识证明验证失败：' + (error instanceof Error ? error.message : '未知错误')
            });
            return false;
          }
        },

        // Progress tracking
        completeStage: (stageId: string) => set(state => {
          const completedStages = [...state.userProgress.completedStages];
          if (!completedStages.includes(stageId)) {
            completedStages.push(stageId);
          }
          return {
            userProgress: {
              ...state.userProgress,
              completedStages
            }
          };
        }),
        
        addBookmark: (time: number) => set(state => ({
          userProgress: {
            ...state.userProgress,
            bookmarks: [...state.userProgress.bookmarks, time]
          }
        })),
        
        updateWatchTime: (duration: number) => set(state => ({
          userProgress: {
            ...state.userProgress,
            totalWatchTime: state.userProgress.totalWatchTime + duration
          }
        })),

        // UI state
        toggleSidebar: () => set(state => ({ sidebarOpen: !state.sidebarOpen })),
        toggleFullscreen: () => set(state => ({ fullscreen: !state.fullscreen })),
        setLoading: (loading: boolean) => set({ loading }),
        setError: (error: string | null) => set({ error }),

        // Performance monitoring
        updatePerformance: (metrics) => set(state => ({
          performance: { ...state.performance, ...metrics }
        }))
      }),
      {
        name: 'zk-proof-demo-storage',
        partialize: (state) => ({
          experienceMode: state.experienceMode,
          audioSettings: state.audioSettings,
          visualSettings: state.visualSettings,
          userProgress: state.userProgress
        })
      }
    ),
    { name: 'zk-proof-demo' }
  )
);

// Export experience modes for use in components
export { EXPERIENCE_MODES };